package com.link.base.base.language.service;

import com.alibaba.fastjson.JSONObject;
import com.link.base.base.language.dao.mybatis.mapper.LanguageMapper;
import com.link.base.base.language.model.LangKeyWord;
import com.link.base.base.language.model.LangModules;
import com.link.base.base.language.model.Language;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.service.BasicServiceException;
import com.link.core.basic.service.BasicServiceImpl;
import com.link.core.basic.service.ServiceException;
import com.link.core.util.RedisUtil;
import com.link.core.util.StringUtils;
import com.link.core.util.UserUtil;
import com.link.core.util.redisclient.LinkRedisClient;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 语言包
 *
 * @author 阳晓琳
 * @date 2020-08-27 11:01:53
 */
@Service
public class LanguageServiceImpl extends BasicServiceImpl<Language> implements LanguageService {

    private static final Logger logger = LogManager.getLogger(LanguageServiceImpl.class);

    private static String LANG_PREX = "LANG_CACHE";

    @Resource
    private LanguageMapper languageMapper;

    @Override
    public BasicMapper<Language> getBasicMapper() {
        return languageMapper;
    }

    @Resource
    private LangModulesService langModulesService;

    @Resource
    private LangKeyWordService langKeyWordService;

    @Override
    public void deleteByIdCascade(Language entity) {
        languageMapper.deleteByIdCascade(entity);
    }

    @Override
    public void refreshCache(Language language) throws Exception {
        JSONObject result = getLangPackResult(language);
        LinkRedisClient jedis = null;
        try {
            //先去redis查询是否有对应语言包
            jedis = RedisUtil.getJedis();
            String lang = language.getAbbrName();
            Long corpId = UserUtil.getUser() != null ? UserUtil.getUser().getCorpid() : 0L;
            String strPrex = LANG_PREX + "_" + lang + "_" + corpId;
            jedis.set(strPrex,result.toJSONString());
        } catch (Exception e) {
            logger.error("更新语言包发生异常: ", e);
        } finally {
            RedisUtil.returnResource(jedis);
        }
    }

    @Override
    public JSONObject langPackage(Language language) throws Exception {
        JSONObject result = new JSONObject();
        //先去redis查询是否有对应语言包
        LinkRedisClient jedis = null;
        try {
            //先去redis查询是否有对应语言包
            jedis = RedisUtil.getJedis();
            String lang = language.getAbbrName();
            Long corpId = UserUtil.getUser() != null ? UserUtil.getUser().getCorpid() : 0L;
            String strPrex = LANG_PREX + "_" + lang + "_" + corpId;
            String resultStr = jedis.get(strPrex);
            if (StringUtils.isNotBlank(resultStr)) {
                result = JSONObject.parseObject(resultStr);
            } else {
                result = getLangPackResult(language);
                jedis.set(strPrex,result.toJSONString());
            }
        } catch (Exception e) {
            logger.error("获取语言包捕获异常: ", e);
        } finally {
            RedisUtil.returnResource(jedis);
        }

        return result;
    }

    public JSONObject getLangPackResult(Language language) throws Exception {
        JSONObject result = new JSONObject();
        List<Language> entityList = languageMapper.queryListByAbbrName(language);
        if (entityList == null || entityList.size() <= 0) {
            throw new BasicServiceException("LanguageError-001");
        }

        Language entity = entityList.get(0);
        List<LangModules> modList = entity.getModList();
        if (modList != null && modList.size() > 0) {
            for (LangModules module : modList) {
                JSONObject modEntity = new JSONObject();
                List<LangKeyWord> langKeyWordList = module.getKeyWordList();
                if (langKeyWordList != null && langKeyWordList.size() > 0) {
                    for (LangKeyWord keyWord : langKeyWordList) {
                        modEntity.put(keyWord.getKeyValue(), keyWord.getKeyName());
                    }
                }
                result.put(module.getModName(), modEntity);
            }
        }

        return result;
    }

    @Override
    public List<Language> langList(Language language) throws Exception {
        return languageMapper.queryListByAbbrName(language);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOtherLanguage(Language language) throws Exception {
        if (Objects.isNull(language)) {
            throw new ServiceException("");
        }
        if (Objects.isNull(language.getId())) {
            throw new ServiceException("");
        }
        // 获取基准语言包
        language = languageMapper.queryLanguageTree(language);
        if (Objects.isNull(language)) {
            throw new ServiceException("");
        }
        List<LangModules> langModules = language.getModList();
        if (CollectionUtils.isEmpty(langModules)) {
            return;
        }
        // 获取其它语言包
        List<Language> otherLang = languageMapper.queryOtherLangList(language);
        if (CollectionUtils.isEmpty(otherLang)) {
            return;
        }
        // 判断

        for (Language updLang : otherLang) {
            List<LangModules> otherLanModLangList = updLang.getModList();
            // 当其它语言包的模块为空时，直接复制其它语言吧
            if (CollectionUtils.isEmpty(otherLanModLangList)) {
                // 整个语言包都进行复制
                copyLanguagePack(updLang, language);
            } else {
                // 源语言包的模块非空时，对源语言包模块进行遍历
                for (LangModules langModule : langModules) {
                    List<LangKeyWord> langKeyWords = langModule.getKeyWordList();
                    // 当语言包模块非空时，判断对应需要赋值的语言包是否存在该模块
                    if (!CollectionUtils.isEmpty(langKeyWords)) {
                        // 需要复制的语言包是否有该模块
                        LangModules hadLangModule = updLangHadLangMod(otherLanModLangList, langModule);

                        if (Objects.isNull(hadLangModule)) {
                            // 不存在模块时，进行整个模块的复制
                            hadLangModule = copyLangModule(updLang, langModule);
                        } else {
                            // 存在语言模块则更新知识模块
                            updLangModule(hadLangModule, langModule);
                        }
                    }
                }
            }

        }


    }

    /**
     * 对已存在的语言模块进行更新
     *
     * @param updLangModule 更新模块
     * @param srcLangModule 源模块
     */
    @Transactional(rollbackFor = Exception.class)
    void updLangModule(LangModules updLangModule, LangModules srcLangModule) throws Exception {
        List<LangKeyWord> srcLangKeys = srcLangModule.getKeyWordList();
        if (CollectionUtils.isEmpty(srcLangKeys)) {
            return;
        }
        List<LangKeyWord> updLangKeys = updLangModule.getKeyWordList();
        if (Objects.isNull(updLangKeys)) {
            updLangKeys = new ArrayList<>(srcLangKeys.size());
        }
        for (LangKeyWord langKeyWord : srcLangKeys) {
            long count = updLangKeys.stream().filter(item -> item.getModId().equals(langKeyWord.getModId())
                    && StringUtils.equals(item.getKeyValue(), langKeyWord.getKeyValue())).count();
            if (count == 0) {
                LangKeyWord newLangKeyWord = new LangKeyWord();
                newLangKeyWord.setModId(updLangModule.getId());
                newLangKeyWord.setKeyValue(langKeyWord.getKeyValue());
                newLangKeyWord.setComments(langKeyWord.getComments());
                newLangKeyWord.setActiveFlag(langKeyWord.getActiveFlag());
                langKeyWordService.insert(newLangKeyWord);
                srcLangKeys.add(newLangKeyWord);
            }
        }

    }

    /**
     * 赋值语言包模块
     * 包括在数据库层面新建
     *
     * @param updLang    语言包
     * @param langModule 语言模块
     * @return 复制的语言包
     */
    @Transactional(rollbackFor = Exception.class)
    LangModules copyLangModule(Language updLang, LangModules langModule) throws Exception {
        if (Objects.isNull(langModule)) {
            return null;
        } else if (StringUtils.isBlank(langModule.getModName())) {
            return null;
        }
        LangModules newLangModules = new LangModules();
        newLangModules.setLangId(updLang.getId());
        newLangModules.setModName(langModule.getModName());
        newLangModules.setComments(langModule.getComments());
        // 数据库新建
        langModulesService.insert(newLangModules);
        List<LangKeyWord> langKeyWords = langModule.getKeyWordList();
        List<LangKeyWord> newLangKeyWords = null;
        if (!CollectionUtils.isEmpty(langKeyWords)) {
            // 赋值模块下的关键字
            newLangKeyWords = copyLangKeyFromSrcLangKeys(newLangModules, langKeyWords);
        }
        return newLangModules;
    }

    /**
     * 在该模块下复制关键字
     * 包括在数据库层面新建
     *
     * @param newLangModules 语言模块头
     * @param langKeyWords   需要复制的关键字
     * @return 该语言模块下新增的关键字
     */
    @Transactional(rollbackFor = Exception.class)
    List<LangKeyWord> copyLangKeyFromSrcLangKeys(LangModules newLangModules, List<LangKeyWord> langKeyWords) throws Exception {
        if (CollectionUtils.isEmpty(langKeyWords)) {
            return null;
        }
        List<LangKeyWord> returnList = new ArrayList<>(langKeyWords.size());
        for (LangKeyWord langKeyWord : langKeyWords) {
            LangKeyWord newLangKeyWord = new LangKeyWord();
            newLangKeyWord.setModId(newLangModules.getId());
            newLangKeyWord.setActiveFlag(langKeyWord.getActiveFlag());
            newLangKeyWord.setKeyName(langKeyWord.getKeyName());
            newLangKeyWord.setKeyValue(langKeyWord.getKeyValue());
            newLangKeyWord.setComments(langKeyWord.getComments());
            returnList.add(newLangKeyWord);
        }
        langKeyWordService.batchInsert(returnList);
        return returnList;
    }

    /**
     * 需要复制的语言包是否有该模块
     *
     * @param otherLanModLangList 需要查找的数组对像
     * @param seaModule           查找的语言包
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    LangModules updLangHadLangMod(List<LangModules> otherLanModLangList, LangModules seaModule) {
        if (CollectionUtils.isEmpty(otherLanModLangList)) {
            return null;
        }
        // @Todo bug待修复
        return (LangModules) otherLanModLangList
                .stream()
                .filter(item -> !Objects.isNull(item) && StringUtils.equals(item.getModName(), seaModule.getModName()))
                .limit(1);
    }

    /**
     * 复制语言包模块
     *
     * @param updLang 需要赋值的语言包
     * @param srcLang 被复制的语言包
     */
    @Transactional(rollbackFor = Exception.class)
    void copyLanguagePack(Language updLang, Language srcLang) throws Exception {
        List<LangModules> srcLangModules = srcLang.getModList();
        if (CollectionUtils.isEmpty(srcLangModules)) {
            return;
        }
        for (LangModules srcLangModule : srcLangModules) {
            copyLangModule(updLang, srcLangModule);
        }
    }


}
